package cn.buk.tms.eotms.service;

import cn.buk.api.pay.alipay.service.AlipayService;
import cn.buk.common.JsonResult;
import cn.buk.common.sc.CommonSearchCriteria;
import cn.buk.common.util.DateUtil;
import cn.buk.jedis.RedisDao;
import cn.buk.tms.eotms.dao.PaymentOrderDao;
import cn.buk.tms.eotms.dto.DtoLoginStatus;
import cn.buk.tms.eotms.dto.RoleInfo;
import cn.buk.tms.eotms.dto.base.UserProfileDto;
import cn.buk.tms.eotms.entity.*;
import com.alibaba.fastjson.JSON;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.Optional;
import java.util.Set;

import static java.nio.charset.StandardCharsets.UTF_8;

/**
 * @author yfdai
 */
@Service
public class UserServiceImpl extends BaseAbstractService implements UserService {

  private final Logger logger = LogManager.getLogger(UserServiceImpl.class);

  @Autowired
  private RedisDao redisDao;

  @Autowired
  private PaymentOrderDao paymentOrderDao;

  @Autowired
  private AlipayService alipayService;

  @Override
  public User getUserByUsername(String username) {
    try {
      return userDao.getUserByUsername(username);
    } catch (Exception e) {
      e.printStackTrace();
      return null;
    }
  }

  @Override
  public UserProfileDto getUserProfile(final int userId) {
    User user = userDao.getUserById(userId);

    UserProfileDto dto = UserProfileDto.createdBy(user);

    dto.setGpMode(this.getGpMode(userId));
    dto.setErrcode(0);

    if (StringUtils.isBlank(dto.getMobile())) {
      //从passenger中获取
      Passenger passenger = enterpriseDao.getPassengerById(user.getPassengerId());
      if (passenger != null) {
        if (StringUtils.isBlank(dto.getEmail())) {
          dto.setEmail(passenger.getEmail());
        }

          dto.setMobile(passenger.getMobile());
      }
    }

    return dto;
  }

  @Override
  public List<RolePrivilege> searchPrivileges(int enterpriseId, int userId) {
    List<RolePrivilege> rolePrivileges = userDao.searchPrivileges(enterpriseId, userId);

    if (enterpriseId == userId) {
      // 管理员
      RolePrivilege o = new RolePrivilege();
      o.setRole(RoleInfo.ROLE_ADMIN);

      rolePrivileges.add(o);
    }

    return rolePrivileges;
  }

  @Override
  public void saveToken(DtoLoginStatus loginStatus) {
    final String value = JSON.toJSONString(loginStatus);

    final String key = "token:" + loginStatus.getToken();
    redisDao.setAndExpire(key, value.getBytes(UTF_8), 60 * 60 * 24 * 7);

    final String keyUserId = "user_" + loginStatus.getUserId() + "_login_status";
    redisDao.setAndExpire(keyUserId, value.getBytes(UTF_8), 60 * 60 * 24 * 7);
  }

  @Override
  public Optional<DtoLoginStatus> getLoginStatusByUserId(final int userId) {
    final String keyUserId = "user_" + userId + "_login_status";
    byte[] bytes = redisDao.get(keyUserId);
    if (bytes != null && bytes.length > 0) {
      String temp = new String(bytes, UTF_8);

      DtoLoginStatus dto = JSON.parseObject(temp, DtoLoginStatus.class);
      return Optional.of(dto);
    } else {
      return Optional.empty();
    }
  }

  @Override
  public JsonResult recharge(final int userId, final double amount0) {
    final double amount = BigDecimal.valueOf(amount0).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();

    if ((amount - 0.01) < 0 || amount > 100000000) {
      return JsonResult.createJsonResult(-1, "输入金额超出范围");
    }

    JsonResult jsonResult = new JsonResult();

    jsonResult.setStatus("OK");

    final int enterpriseId = getEnterpriseIdByUserId(userId);
    final int ownerId = getOwnerIdByUserId(userId);

    //保存支付订单
    //商户订单号
    final String outTradeNo = "10"+ enterpriseId + "0" + userId + "0" +  DateUtil.formatDate(DateUtil.getCurDateTime(), "yyyyMMddHHmmss");
    PaymentOrder order = new PaymentOrder();
    order.setEnterpriseId(enterpriseId);
    order.setTradeNo(outTradeNo);
    order.setPrice(amount);
    order.setStatus(0);
    order.setUserId(userId);
    order.setOwnerEnterpriseId(ownerId);
    paymentOrderDao.create(order);

    String url = alipayService.createPaymentParams(outTradeNo, amount, "recharge");

    logger.info(url);

    jsonResult.setUrl(url);

    return jsonResult;
  }

  @Override
  public Set<String> loadRolesByUserId(final int enterpriseId, final int userId) {
    return getRolesByUserId(enterpriseId, userId);
  }

  @Override
  public List<AmountHistory> searchTransHistory(final int userId, CommonSearchCriteria sc) {
    final int ownerId = getOwnerIdByUserId(userId);
    final int enterpriseId = getEnterpriseIdByUserId(userId);
    return userDao.searchTransHistory(ownerId, enterpriseId, sc);
  }

  @Override
  public void createUserBindWeixin(final int ownerId, final String username, final String openid, final int enterpriseId, final int userId) {
    if (ownerId == enterpriseId) {
      throw new RuntimeException("can not bind openid(" + ownerId + ", " + username + ", " + openid + ", " + enterpriseId + ", " + userId);
    }
    UserBindWeixin o = new UserBindWeixin();

    o.setOwnerId(ownerId);
    o.setWeixinOpenId(openid);
    o.setEnterpriseId(enterpriseId);
    o.setUsername(username);
    o.setUserId(enterpriseId);
    userDao.createUserBindWeixin(o);
  }

  @Override
  public UserBindWeixin getUserByOpenid(int ownerId, String openid) {
    return userDao.getUserByOpenid(ownerId, openid);
  }

  @Override
  public User getUserById(int userId) {
    return userDao.getUserById(userId);
  }


  @Override
  public int getGpMode(final int userId) {
    final int ownerId = getOwnerIdByUserId(userId);
    final int customerId = getCustomerIdByUserId(userId);

    CustomerServiceTemplate tpl = enterpriseDao.searchServiceTemplateByCustomer(ownerId, customerId);
    return tpl == null ? 0 : tpl.getGpMode();
  }
}
